package com.atguigu.gulimall.product;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;


/**
 * 目前缓存使用的就是Spring-cache。因为能够满足业务需求，但是redisson也有例子，涉及到并发锁，缓存的模式不足，脏数据等的设计
 * SpringCache缓存使用步骤：
 *  0、加入依赖：
 *         <dependency>
 *             <groupId>org.springframework.boot</groupId>
 *             <artifactId>spring-boot-starter-cache</artifactId>
 *         </dependency>
 *  1、在配置文件中加入：spring.cache.type=redis
 *  2、开启缓存的功能 @EnableCaching
 *  3、只需要使用注解就能完成相关缓存的操作
 *
 * SpringCache不足：
 *  1、读模式：
 *      缓存穿透：查询一个null数据。解决：缓存空数据：ache-null-values=true (配置中配置)
 *      缓存击穿：大量并发进来同时查询一个正好过期的数据。解决：加锁。默认是无加锁的。@Cacheable(value = {"category"},key = "#root.method.name",sync=true) 加上sync=true(加锁，解决击穿)
 *      缓存雪崩：大量的key同时过期，解决：加随机时间，加过期时间。spring.cache.redis.time-to-live=36000000
 *  2、写模式：（缓存与数据库一致）
 *      1、读写加锁
 *      2、引入Canal，感知到mysql的更新去更新数据库
 *      3、读多写多，直接去查询数据库
 *  总结：常规数据（读多写少，即时性一致性要求不高的数据）完全可以使用Spring-cache（只要缓存的数据有过期时间就足够了）
 *      特殊数据：特殊设计
 *
 */
@EnableRedisHttpSession // 整合redis作为session存储，
@SpringBootApplication
@MapperScan("com.atguigu.gulimall.product.dao") // 数据源包
@EnableDiscoveryClient //nacos注册中心客户端
@EnableFeignClients//开启远程调用
public class GulimallProductApplication {

    public static void main(String[] args) {
        SpringApplication.run(GulimallProductApplication.class, args);
    }

}
